<?php
class Query
{
	// Для Where
	public $fields = Array();
	private $fieldsIN = Array();
	
	// Для SET;
	private $sfields = Array();
	// Значения полей для Execute
	private $fvalue = Array();
	public $tagValue = Array();
	
	private $limit = "";
	public $order = Array();
	
	public function limit($limit, $offset = null){
		$this->limit = " OFFSET {$limit}";
		if($offset){
			$this->limit.=" LIMIT {$offset}";
		}
		
		return $this;
	}
	
	public function order($field,$type = "DESC"){
		array_push($this->order,Array("field"=>$field,"type"=>$type));
		return $this;
	}
	
	public function sortByOrder($result){
		$order = $this->order;
		function cmpOrder($a, $b, &$order){//
			$diff=0;			
				$i=0;
				while($i<count($order)&&$diff==0){
					$ida=$a->$order[$i]['field'];
					$idb=$b->$order[$i]['field'];
					if ($ida == $idb){
						$i++;
					}elseif($order[$i]['type']=="ASC"){
						$diff=($ida < $idb) ? -1 : 1;
					}elseif($order[$i]['type']=="DESC"){
						$diff=($ida < $idb) ? -1 : 1;
					}
				//echo '<br/>'.$i.' '.$diff.' '.$order[$i]['type'].' '.$order[$i]['field'].' '.$ida.' < '.$idb;
				}
			return ($diff==-1)?true:false;
		}
		function quickSort($left,$right,&$result, &$order){
			$i=$left;
			$j=$right;
			$x=$result[(int)(($left+$right)/2)];
			$w=NULL;
			do{
				while (cmpOrder($result[$i],$x,$order)) $i++;
				while (cmpOrder($x,$result[$j],$order)) $j--;
				if($i<=$j){
					$w=$result[$i];
					$result[$i]=$result[$j];
					$result[$j]=$w;
					$i++;
					$j--;
				}
			}while($i<=$j);
			//echo $left.' '.$i.' '.$j.' '.$right;
			if($left<$j) quickSort($left,$j,$result,$order);
			if($i<$right) quickSort($i,$right,$result,$order);	
		//echo $left.' '.$right;
		return $result;
		}
		if($this->order){
		$a=0;$b=count($result)-1;
			quickSort($a,$b,$result,$order);		
		}
		return $result;
	}
	
	
	
	public function field($field, $val, $op = "=", $delimetr = "AND"){
		$cnt = count($this->fields);
		$valID = "w_{$field}{$cnt}";
		$this->fvalue[$valID] = $val;
		if( $op == "=" ){
			$this->tagValue[] = Array( "field" => $field, "val" => $val);
		}
		array_push($this->fields, Array("field"=> $field, "val" => ":{$valID}", "op" => $op));
		return $this;
	}
	
	/**
	* Для формирования строки вида
	* $field IN ($val[1],$val[2])
	* @param mixed $field - Имя поля
	* @param mixed $val - Одно из значений поля в ИН
	* @param mixed $op - IN or NOT IN
	*/
	public function fieldIN($field, $val, $op = "IN"){
		$cnt 	= count($this->fieldsIN[$field]["values"]); 
		$valID  = "wfi_{$field}{$cnt}";
		$add = true;
		if(!isset($this->fieldsIN[$field])){
			$this->fieldsIN[$field]= Array("field"=>$field,"op" => $op, "values" => Array(),"real"=>array());
		}elseif($cnt > 0){
			foreach($this->fieldsIN[$field]["real"] as $value){
				if($value == $val){
					$add = false;
				}
			}
		}
		if($add){
			$this->fvalue[$valID] = $val;
			$this->tagValue[] = Array( "field" => $field, "val" => $val);
			array_push($this->fieldsIN[$field]["values"],":{$valID}");
			array_push($this->fieldsIN[$field]["real"], $val);
		}
		return $this;
	}
	
	
	public function fieldSet($field, $val){
		$cnt = count($this->sfields);
		$valID = "s_{$field}{$cnt}";
		$this->fvalue[$valID] = $val;
		array_push($this->sfields, Array("field"=>$field,"val"=>":{$valID}"));
		return $this;
	}
	
	
	
	public function getValue(){ 
		ksort($this->fvalue);
		return $this->fvalue;
	}
	
	// Строка для запроса SET ...
	public function toStringSet(){
		$ret = array();
		if(count($this->sfields) > 0){
			foreach($this->sfields as $k => $v){
				$ret[] = $v["field"] ." = ". $v["val"];
			}			
			
		}else{
			return false;
		}
		return implode(", ", $ret);
	}
	
	// Строка запроса WHERE ... ORDER BY ... Limit .. OFFSET ..
	public function toString(){
		$ret = Array();
		$return = "";
		if(count($this->fvalue) > 0){
			$return.=" WHERE ";
			if(!empty($this->fields)){
				foreach($this->fields as $k => $v){
					$ret[] = "{$v["field"]} {$v["op"]} {$v["val"]}";
				}
			}
			if(!empty($this->fieldsIN)){
				foreach($this->fieldsIN as $k => $v){
					$ret[] = "{$v["field"]} {$v["op"]} (".implode(",",$v["values"]).")";
				}
			}
			$return .= implode(" AND ", $ret);
		}		
		
		if( count($this->order) > 0 ){
			$return.= " ORDER BY ";
			$ret = array();
			foreach($this->order as $k => $v){
				$ret[] = "{$v["field"]} {$v["type"]}";
			}
			$return .= implode(" , ", $ret);
		}
		
		$return.= " ".$this->limit;
		return $return;
	}
	
}

?>
